package com.huilian.tool.weixin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.huilian.tool.common.config.WeixinConfig;
import com.huilian.tool.common.utils.*;
import com.huilian.tool.redis.ToolRedisKey;
import com.huilian.tool.weixin.enums.ActionNameEnum;
import com.huilian.tool.weixin.enums.EventTypeEnum;
import com.huilian.tool.weixin.enums.MessageTypeEnum;
import com.huilian.tool.weixin.enums.SendMessageTypeEnum;
import com.huilian.tool.weixin.exception.WeixinException;
import com.huilian.tool.weixin.service.WeiXinMsgEventService;
import com.huilian.tool.weixin.service.WeixinService;
import com.huilian.tool.weixin.vo.Articles;
import com.huilian.tool.weixin.vo.Menu;
import com.huilian.tool.weixin.vo.ParamQrCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.HttpClients;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @authou 少凡
 * @Date 2019-04-12 16:04
 */
@Slf4j
@Service
public class WeixinServiceImpl implements WeixinService {

    @Resource
    private WeiXinMsgEventService weiXinMsgEventService;

    @Resource
    private RedisTemplate<String, Serializable> redisCacheTemplate;

    @Resource
    private WeixinConfig weixinConfig;

    private String URL = "http://charge.huilianpay.com/";

    private String OUTPUT_URL = "http://output.huilianpay.com/";

    private String USER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN";

    private String OPENID_URL = OUTPUT_URL + "openId?redirectUrl=%s&attach=%s";

    /**
     * 微信授权码网址
     */
    private final String URL_GET_WEIXIN_AUTH_CODE = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect&connect_redirect=1";

    /**
     * 微信通过code换取网页授权access_token
     */
    private final String URL_GET_WEIXIN_OPENID = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";

    private String URL_GET_WEIXIN_USER_INFO = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";

    /**
     * 获取微信accessToken网址
     */
    private String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appId=%s&secret=%s";

    private String SEND_TEMPLATE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";

    private String COMPONENT_VERIFY_TICKET = "weixin_component_verify_yicket";

    private String COMPONENT_VERIFY_TOKEN = "weixin_component_verify_token";

    private String JSAPI_TICKET = "weixin_jsApi_ticket";

    private String ACCESS_TOKEN = "weixin_access_token";

    private String HUI_USERINFO_URL = "https://open.huilianpay.com/output/userInfo?redirectUrl=%s&attach=%s";


    /**
     * 微信开启开发者模式 配置接口
     *
     * @param request
     * @return
     */
    @Override
    public String openDeveloperModel(HttpServletRequest request, String token) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");

        if (CheckUtil.checkSignature(signature, timestamp, nonce, token)) {
            return echostr;
        }
        return null;
    }

    @Override
    public Map<String, String> getWeiXinJsSdkConfig(String url, String jsApiTicket) {
        String noncestr = UUID.randomUUID().toString();
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        String param = "jsapi_ticket=%s&noncestr=%s&timestamp=%s&url=%s";
        String content = String.format(param, jsApiTicket, noncestr, timestamp, url);

        String signature = SHA1.encode(content);

        Map<String, String> map = new HashMap<String, String>();
        //放值进入MAP。
        map.put("appId", weixinConfig.getAppId());
        map.put("timestamp", timestamp);
        map.put("nonceStr", noncestr);
        map.put("signature", signature);
        log.info(map.toString());
        return map;
    }

    /**
     * 微信消息管理
     *
     * @param request
     * @return
     * @throws DocumentException
     * @throws AesException
     * @throws IOException
     */
    @Override
    public String messageManage(HttpServletRequest request) throws DocumentException, AesException, IOException {
        Map<String, String> map = MessageUtil.xmlToMap(request, weixinConfig);

        String msgType = map.get("MsgType");

        String message = null;

        if (MessageTypeEnum.EVENT.getCode().equals(msgType)) {
            //事件处理
            String ticket = map.get("Ticket");
            String event = map.get("Event");
            if (StringUtils.isNotBlank(event)) {
                if (EventTypeEnum.UNSUBSCRIBE.getCode().equals(event)) {
                    //用户取关事件
                    message = weiXinMsgEventService.unsubscribeService(map);
                } else if (EventTypeEnum.SUBSCRIBE.getCode().equals(event) && StringUtils.isNotBlank(ticket)) {
                    //用户未关注，扫带参数二维码事件
                    message = weiXinMsgEventService.noSubscribeScanService(map);
                } else if (EventTypeEnum.SCAN.getCode().equals(event)) {
                    //用户已关注，扫码带参数二维码
                    message = weiXinMsgEventService.subscribeScanService(map);
                } else if (EventTypeEnum.LOCATION.getCode().equals(event)) {
                    //用户上报地址位置事件
                    message = weiXinMsgEventService.locationEventService(map);
                } else if (EventTypeEnum.CLICK.getCode().equals(event)) {
                    //自定义菜单点击事件
                    message = weiXinMsgEventService.clickMenuService(map);
                } else if (EventTypeEnum.VIEW.getCode().equals(event)) {
                    //点击菜单跳转链接时的事件推送
                    message = weiXinMsgEventService.viewService(map);
                } else {
                    log.error("未知事件");
                }
            } else {
                if (MessageTypeEnum.TEXT.getCode().equals(msgType)) {
                    //文本信息
                    message = weiXinMsgEventService.textMsgService(map);
                } else if (MessageTypeEnum.IMAGE.getCode().equals(msgType)) {
                    //图片信息
                    message = weiXinMsgEventService.imageMsgService(map);
                } else if (MessageTypeEnum.VOICE.getCode().equals(msgType)) {
                    //语音消息
                    message = weiXinMsgEventService.voiceMsgService(map);
                } else if (MessageTypeEnum.VIDEO.getCode().equals(msgType)) {
                    //视频消息
                    message = weiXinMsgEventService.videoMsgService(map);
                } else if (MessageTypeEnum.SHORT_VIDEO.getCode().equals(msgType)) {
                    //小视频消息
                    message = weiXinMsgEventService.shortVideoMsgService(map);
                } else if (MessageTypeEnum.LOCATION.getCode().equals(msgType)) {
                    //地址位置消息
                    message = weiXinMsgEventService.locationMsgService(map);
                } else if (MessageTypeEnum.LINK.getCode().equals(msgType)) {
                    //链接消息
                    message = weiXinMsgEventService.linkMsgService(map);
                } else {
                    log.error("未知消息");
                }
            }
        }

        String timeStamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");

        WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(weixinConfig.getEncodingAesKey());

        return wxBizMsgCrypt.encryptMsg(message, timeStamp, nonce, weixinConfig.getAppId(), weixinConfig.getToken());
    }


    /**
     * 获取微信公众号带参二维码
     *
     * @param accessToken    微信基础服务Token
     * @param actionNameEnum
     * @param sceneId        参数
     * @param expireSeconds  有效时间可不传
     * @return
     */
    @Override
    public JSONObject getQrCodeParam(String accessToken, ActionNameEnum actionNameEnum, String sceneId, String... expireSeconds) {
        String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + accessToken;
        String body = null;
        if (StringUtils.isEmpty(String.valueOf(expireSeconds))) {
            body = "{\"action_name\": \"%s\", \"action_info\": {\"scene\": {\"scene_id\": %s}}}";
            body = String.format(body, actionNameEnum.getCode(), sceneId);
        } else {
            body = "{\"expire_seconds\": \"%s\",\"action_name\": \"%s\", \"action_info\": {\"scene\": {\"scene_id\": %s}}}";
            body = String.format(body, expireSeconds, actionNameEnum.getCode(), sceneId);
        }

        String restul = HttpServiceUtil.httpPost(url, body);
        int index = restul.indexOf("url");
        JSONObject jsonObject = null;
        if (index != -1) {
            jsonObject = JSONObject.parseObject(restul);
            ParamQrCode qrCode = new ParamQrCode();
            qrCode.setUrl(jsonObject.getString("url"));
            int no = restul.indexOf("expire_seconds");
            if (no != -1) {
                qrCode.setExpireSeconds(jsonObject.getString("expire_seconds"));
            }
            qrCode.setTicket(jsonObject.getString("ticket"));
//            return ServerResponse.createBySuccess(qrCode);
        } else {
//            return ServerResponse.createByErrorMessage(restul);
        }
        //TODO 这里还没有改好
        return jsonObject;
    }

    @Override
    public String createMenu(String token, Menu menu) {

        String jsonMenu = JSON.toJSONString(menu);

        String url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + token;
        try {
            String result = HttpServiceUtil.httpPost(url, jsonMenu);
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject != null) {
                int errCode = jsonObject.getInteger("errcode");
                if (errCode == 0) {
                    log.info("创建菜单成功");
                    return "{\"errcode\":0,\"errmsg\":\"ok\"}";
                } else {
                    log.error(result);
                    return result;
                }
            }

        } catch (Exception e) {
            log.error(e.getMessage());
        }

        throw new WeixinException("创建菜单发生未知错误！");
    }

    @Override
    public BufferedImage createBusinessCards(Integer userId, String nickName, String headImgUrl, String qrCodeUrl, String fileExt) throws Exception {

        String path = RootPathUtil.getRootPath();

        String bgPath = path + "bgPath.jpg";

        //背景图
        Image bgImg = new ImageIcon(bgPath).getImage();

        //保存头像到本地
        String headImgPath = path + userId + "_headImg.jpg";
        DownLoadFileUtil.downloadFile(headImgUrl, headImgPath);
        Image headerImg = new ImageIcon(headImgPath).getImage();

        //生成推广二维码
        QRCodeUtil.encode(qrCodeUrl, null, path, userId + "_qrCode.jpg", true);
        Image qrCodeImg = new ImageIcon(path + userId + "_qrCode.jpg").getImage();

        int width = bgImg.getWidth(null); //源图片宽度
        int height = bgImg.getHeight(null); //源图片高度

        BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics2D g = bimage.createGraphics();

        if (fileExt.equals("png")) {
            bimage = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
            g.dispose();
            g = bimage.createGraphics();
        }

        g.setColor(new Color(14, 14, 14));
        g.setStroke(new BasicStroke(1));

        Color color = new Color(1.0F, 0.75F, 0.0F, 0.45F);
        g.setBackground(color);

        //绘制背景
        g.drawImage(bgImg, 0, 0, null);

        g.drawImage(qrCodeImg, 385, 480, 230, 230, null); //添加图标中间两个数字参数 是设定位置
        g.drawImage(headerImg, 50, 830, 88, 88, null);
        g.setFont(new Font("Microsoft YaHei", Font.PLAIN, 30));
        g.drawString(nickName, 160, 880); //添加用户名文字
        g.dispose();
        bimage.flush();

        return bimage;
    }

    @Override
    public void sendServiceMessage(String fromUserName, String msgType, String message, String accessToken) {
        String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + accessToken;
        Map<String, Object> hashMap = new HashedMap();
        hashMap.put("touser", fromUserName);
        hashMap.put("msgtype", msgType);
        if (msgType.equals("text")) {
            Map<String, String> text = new HashedMap();
            text.put("content", message);
            hashMap.put("text", text);
        } else if (msgType.equals("image")) {
            Map<String, String> image = new HashedMap();
            image.put("media_id", message);
            hashMap.put("image", image);
        } else if (msgType.equals("news")) {
            JSONObject jsonObject = JSON.parseObject(message);
            Map<String, Object> news = new HashedMap();
            java.util.List<Articles> articlesList = new ArrayList<>();
            Articles articles = new Articles();
            articles.setTitle(jsonObject.getString("title"));
            articles.setDescription(jsonObject.getString("description"));
            articles.setPicurl(jsonObject.getString("picUrl"));
            articles.setUrl(jsonObject.getString("url"));
            articlesList.add(articles);
            news.put("articles", articlesList);
            hashMap.put("news", news);
        } else if (msgType.equals(SendMessageTypeEnum.MINIPROGRAMPAGE.getCode())) {
            JSONObject jsonObject = JSON.parseObject(message);
            Map<String, String> miniprogrampage = new HashedMap();
            miniprogrampage.put("title", jsonObject.getString("title"));
            miniprogrampage.put("appid", jsonObject.getString("appid"));
            miniprogrampage.put("pagepath", jsonObject.getString("pagepath"));
            miniprogrampage.put("thumb_media_id", jsonObject.getString("thumb_media_id"));
            hashMap.put("miniprogrampage", miniprogrampage);

        }
        String msg = JSON.toJSONString(hashMap);
        String res = HttpServiceUtil.httpPost(url, msg);
        log.info("微信发送:{}", res);
    }

    @Override
    public String getOpenId(String redirectUrl, String attach, HttpServletRequest request) throws UnsupportedEncodingException {

        String myRedirectUrl = weixinConfig.getUrl() + "/client/api/weixin/outPutOpenId";
        URLEncoder.encode(myRedirectUrl, "UTF-8");
        String scope = "snsapi_base";
        //用户传递进来，获取到Code后回调地址，将他放到state字段带到请求中，微信会原样返回
        String userRedirectUrl = redirectUrl + "?attach=" + attach;

        userRedirectUrl = URLEncoder.encode(userRedirectUrl, "UTF-8");
        final String url = String.format(URL_GET_WEIXIN_AUTH_CODE, weixinConfig.getAppId(), myRedirectUrl, scope, userRedirectUrl);
        log.info("请求获取OpenId的回调地址:{},附加参数:{}: ", userRedirectUrl, attach);

        return "redirect:" + url;
    }

    @Override
    public String responseOpenId(HttpServletRequest request) {

        StringBuffer url = new StringBuffer();

        //微信返回的授权码
        String code = request.getParameter("code");

        //请求用户的回调地址
        String redirectUrl = request.getParameter("state");

        String reqUrl = String.format(URL_GET_WEIXIN_OPENID, weixinConfig.getAppId(), weixinConfig.getAppSecret(), code);


        String result = HttpServiceUtil.httpGet(reqUrl);
        int index = result.indexOf("openid");
        String openId = null;
        if (index != -1) {
            JSONObject jsonObject = JSONObject.parseObject(result);
            openId = jsonObject.getString("openid");
        } else {
            log.error("获取OpenId失败！{}", result);
            throw new RuntimeException(result);
        }

        url.append(redirectUrl).append("&openId=").append(openId);

        return "redirect:" + url.toString();
    }


    @Override
    public String getComponentAccessToken(String appId, String appSecret) throws IOException {
        String componentTicket = (String) redisCacheTemplate.opsForValue().get(COMPONENT_VERIFY_TICKET + "_" + appId);
//        String componentTicket = "ticket@@@NABfGUjs_HBOt5UeBeqvuP9aiLz4AAZdyH78jh4rK8arHAl0HRHQR3MPAjkVjiyb_BSdXj-RahJlUbJltZL-ww";
        String key = COMPONENT_VERIFY_TOKEN + "_" + appId;
        String componentToken = (String) redisCacheTemplate.opsForValue().get(key);
        if (componentToken == null) {
            log.info("componentTicket: {}", componentTicket);
            String url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
            JSONObject json = new JSONObject();
            json.put("component_appid", appId);
            json.put("component_appsecret", appSecret);
            json.put("component_verify_ticket", componentTicket);
            String result = HttpServiceUtil.httpPostJson(url, json);
            //包含错误信息直接外抛
            if (result.contains("errmsg")) {
                throw new WeixinException(result);
            }
            JSONObject jsonObject = JSONObject.parseObject(result);
            log.info("{}", result);
            componentToken = jsonObject.getString("component_access_token");
            redisCacheTemplate.opsForValue().set(key, componentToken, 100, TimeUnit.MINUTES);
        }
        return componentToken;
    }

    @Override
    public String getUserInfo(String redirectUrl, String attach, HttpServletRequest request, String wapBackEndUrl) throws UnsupportedEncodingException {
        String userAgent = request.getHeader("User-Agent").toLowerCase();
        String mobile = (String) request.getAttribute("mobile");
        String url = "";
        if (userAgent.contains("alipayclient")) {
            log.info("通过支付宝获取用户信息");
            url = String.format(HUI_USERINFO_URL, redirectUrl, attach);
        } else if (userAgent.contains("micromessenger")) {
            log.info("通过微信获取用户信息");
            String myRedirectUrl = wapBackEndUrl + "/api/weixin/outPutUserInfo";
            URLEncoder.encode(myRedirectUrl, "UTF-8");
            String scope = "snsapi_userinfo";
            //用户传递进来，获取到Code后回调地址，将他放到state字段带到请求中，微信会原样返回
            String userRedirectUrl = redirectUrl + "?attach=" + attach + "&mobile=" + mobile;
            log.info("请求获取OpenId的回调地址:{},附加参数:{}: ", userRedirectUrl, attach);
            userRedirectUrl = URLEncoder.encode(userRedirectUrl, "UTF-8");
            url = String.format(URL_GET_WEIXIN_AUTH_CODE, weixinConfig.getAppId(), myRedirectUrl, scope, userRedirectUrl);
            log.info("请求获取OpenId的回调地址:{},附加参数:{}: ", userRedirectUrl, attach);
        }
        return "redirect:" + url;
    }

    @Override
    public String responseUserInfo(HttpServletRequest request) throws UnsupportedEncodingException {
        StringBuffer url = new StringBuffer();
        //微信返回的授权码
        String code = request.getParameter("code");

        //请求用户的回调地址
        String redirectUrl = request.getParameter("state");

        String reqUrl = String.format(URL_GET_WEIXIN_OPENID, weixinConfig.getAppId(), weixinConfig.getAppSecret(), code);

        log.info("reqUrl:" + reqUrl);
        String result = HttpServiceUtil.httpGet(reqUrl);
        log.info("result:" + result);

        String userAgent = request.getHeader("User-Agent").toLowerCase();
        String userInfo = "";
        if (userAgent.contains("micromessenger")) {
            int index = result.indexOf("openid");
            if (index != -1) {
                JSONObject jsonObject = JSONObject.parseObject(result);
                String openId = jsonObject.getString("openid");
                String accessToken = jsonObject.getString("access_token");
                String refreshToken = jsonObject.getString("refresh_token");
                String userInfoUrl = String.format(URL_GET_WEIXIN_USER_INFO, accessToken, openId);
                userInfo = HttpServiceUtil.httpGet(userInfoUrl);

                /**
                 * {"openid":"oIc_V57vlRdv6pc5QnqkSq61DFuM","nickname":"᭄赵᭄ᩚ刚💗এ华ꦿ13782616925","sex":0,"language":"","city":"","province":"","country":"","headimgurl":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/YT2QHmMsibFiabjK2ibva5QbtibWxQIEUqLl42ZL7DHI2QC0iasTuY3y9fNQDL1bQL4av8HCkVEx35CFq4dqO4DBqqQ\/132","privilege":[],"unionid":"oCJdU1fFyc8h7xiYW88NjAKBqwrk"}:
                 *
                 * {"errcode":48001,"errmsg":"api unauthorized, rid: 665463a7-4e6989e0-0d051cd2"}:
                 */
                JSONObject userInfoJsonObject = JSONObject.parseObject(userInfo);
                String openIdByUserInfo = userInfoJsonObject.getString("openid");
                if (StringUtils.isEmpty(openIdByUserInfo)) {
                    JSONObject ui = new JSONObject();
                    ui.put("openid", openId);
                    userInfo = JSON.toJSONString(ui);
                    log.info("默认UserInfo: {}: ", userInfo);
                } else {
                    log.info("获取UserInfo成功: {}: ", userInfo);
                }
            } else {
                log.error("获取用户信息失败！{}", result);
                throw new RuntimeException(result);
            }
        }
        url.append(redirectUrl).append("&userInfo=").append(URLEncoder.encode(userInfo, "UTF-8"));

        return "redirect:" + url;
    }



    @Override
    public String getAccessToken() {
        final String key = String.format(ToolRedisKey.WEI_XIN_ACCESS_TOKEN, weixinConfig.getAppId());
        String accessToken = (String) redisCacheTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(accessToken)) {
            String accessTokenUrl = String.format(ACCESS_TOKEN_URL, weixinConfig.getAppId(), weixinConfig.getAppSecret());
            JSONObject accessTokenJson = JSONObject.parseObject(HttpServiceUtil.httpGet(accessTokenUrl));
            log.info(JSON.toJSONString(accessTokenJson));
            accessToken = (String) accessTokenJson.get("access_token");
            redisCacheTemplate.opsForValue().set(key, accessToken, 1, TimeUnit.HOURS);
        }
        return accessToken;
    }

    @Override
    public String getAccessToken(String appId, String appSecret) {
        final String key = String.format(ToolRedisKey.WEI_XIN_ACCESS_TOKEN, appId);
        String accessToken = (String) redisCacheTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(accessToken)) {
            String accessTokenUrl = String.format(ACCESS_TOKEN_URL, appId, appSecret);
            JSONObject accessTokenJson = JSONObject.parseObject(HttpServiceUtil.httpGet(accessTokenUrl));
            log.info(JSON.toJSONString(accessTokenJson));
            accessToken = (String) accessTokenJson.get("access_token");
            redisCacheTemplate.opsForValue().set(key, accessToken, 1, TimeUnit.HOURS);
        }
        return accessToken;
    }

    @Override
    public String getJsApiTicket() {
        String jsApiTicket = (String) redisCacheTemplate.opsForValue().get(JSAPI_TICKET);
        if (StringUtils.isEmpty(jsApiTicket)) {
            String accessToken = this.getAccessToken();
            if (StringUtils.isEmpty(accessToken)) {
                log.error("获取微信accessToken失败: " + accessToken);
                return null;
            }
            System.out.println("accessToken: " + accessToken);
            String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";

            String result = HttpServiceUtil.httpGet(url);
            JSONObject jsonObject = JSONObject.parseObject(result);
            int index = result.indexOf("ticket");
            if (index == -1) {
                log.error("获取微信JsapiTicket失败: " + result);
                redisCacheTemplate.delete(ACCESS_TOKEN);
                return null;
            } else {
                jsApiTicket = jsonObject.getString("ticket");
                redisCacheTemplate.opsForValue().set(JSAPI_TICKET, jsApiTicket, 110, TimeUnit.MINUTES);
            }
        }
        return jsApiTicket;
    }

    @Override
    public JSONObject getUserInfo(String accessToken, String openId) {
        String url = String.format(USER_INFO_URL, accessToken, openId);
        String result = HttpServiceUtil.httpGet(url);
        return JSONObject.parseObject(result);
    }

    @Override
    public String mediaUpload(String authorizerToken, File file, String type) {
        String res = null;
        StringBuffer url = new StringBuffer("https://api.weixin.qq.com/cgi-bin/media/upload");
        url.append("?access_token=").append(authorizerToken);
        url.append("&type=").append(type);

        HttpPost httpPost = new HttpPost(String.valueOf(url));
        FileBody fileBody = new FileBody(file);
        HttpEntity reqEntity = MultipartEntityBuilder.create()
                .addPart("media", fileBody)
                .build();
        httpPost.setEntity(reqEntity);
        try {
            CloseableHttpResponse httpResponse = HttpClients.createDefault().execute(httpPost);
            InputStream content = httpResponse.getEntity().getContent();
            res = IOUtils.toString(content, "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return res;
    }

    @Override
    public String SendTemplateMessage(JSONObject jsonObject) {
        String accessToken = this.getAccessToken();
        String url = String.format(SEND_TEMPLATE_MESSAGE, accessToken);

        JSONObject result = JSONObject.parseObject(HttpServiceUtil.httpPost(url, jsonObject.toString()));
        return result.getString("errmsg");
    }
}
